﻿#include "FITKAbaInteractionPropertyContact.h"
#include "FITKAbaInteractionContactTangentialBehavior.h"
#include "FITKAbaInteractionContactNormalBehavior.h"
#include "FITKAbaInteractionContactGeometricProperty.h"

namespace Interface {

FITKAbaInteractionPropertyContact::~FITKAbaInteractionPropertyContact()
{
    this->clearAllBehaviors();
}

FITKAbaAbstractInteractionProperty::FITKAbaInteractionPropertyType FITKAbaInteractionPropertyContact::getInteractionPropertyType() const
{
    return Interface::FITKAbaAbstractInteractionProperty::FITKAbaInteractionPropertyType::Contact;
}

bool FITKAbaInteractionPropertyContact::copy(Core::FITKAbstractDataObject* obj)
{
    FITKAbaInteractionPropertyContact* c = dynamic_cast<FITKAbaInteractionPropertyContact*>(obj);
    if (obj == nullptr)
        return false;
    this->setDataObjectName(c->getDataObjectName());
    this->clearAllBehaviors();
    for (FITKAbaInteractionContactBehavior* b : c->m_behaviors)
    {
        auto type = b->getBehaviorType();
        this->addBehavior(type);
        FITKAbaInteractionContactBehavior* newBehavior = this->getBehavoir(type);
        switch (type)
        {
        case Interface::FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::TangentialBehavior:
        {
            FITKAbaInteractionContactTangentialBehavior* newB = dynamic_cast<FITKAbaInteractionContactTangentialBehavior*>(newBehavior);
            FITKAbaInteractionContactTangentialBehavior* olbB = dynamic_cast<FITKAbaInteractionContactTangentialBehavior*>(b);
            *newB = *olbB;
        }
            break;
        case Interface::FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::NormalHehavior:
        {
            FITKAbaInteractionContactNormalBehavior* newB = dynamic_cast<FITKAbaInteractionContactNormalBehavior*>(newBehavior);
            FITKAbaInteractionContactNormalBehavior* oldB = dynamic_cast<FITKAbaInteractionContactNormalBehavior*>(b);
            *newB = *oldB;
        }
            break;
            
        case Interface::FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::GeometricProperty:
        {
            FITKAbaInteractionContactGeometricProperty* newB = dynamic_cast<FITKAbaInteractionContactGeometricProperty*>(newBehavior);
            FITKAbaInteractionContactGeometricProperty* oldB = dynamic_cast<FITKAbaInteractionContactGeometricProperty*>(b);
            *newB = *oldB;
        }
            break;
        case Interface::FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::ThermalConductance:
            break;
        default:
            break;
        }
    }
    return true;
}

QList<FITKAbaInteractionContactBehavior *> FITKAbaInteractionPropertyContact::getBehaviors()
{
    return m_behaviors;
}

bool FITKAbaInteractionPropertyContact::hasBehavior(FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType type) const
{
    for (auto b: m_behaviors)
    {
        if (b->getBehaviorType() == type)
            return true;
    }
    return false;
}

void FITKAbaInteractionPropertyContact::addBehavior(FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType type)
{
    if (this->hasBehavior(type))
        return;
    FITKAbaInteractionContactBehavior* behavior{nullptr};
    switch (type)
    {
    case Interface::FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::TangentialBehavior:
        behavior = new FITKAbaInteractionContactTangentialBehavior();
        break;
    case Interface::FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::NormalHehavior:
        behavior = new FITKAbaInteractionContactNormalBehavior();
        break;
    case  FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::GeometricProperty:
        behavior = new FITKAbaInteractionContactGeometricProperty();
        break;
    case Interface::FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType::ThermalConductance:
        break;
    default:
        break;
    }
    if (behavior == nullptr)
        return;
    m_behaviors.push_back(behavior);
}

void FITKAbaInteractionPropertyContact::removeBehavior(FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType type)
{
    if (!this->hasBehavior(type))
        return;
    auto b = this->getBehavoir(type);
    m_behaviors.removeOne(b);
    delete b;
}

FITKAbaInteractionContactBehavior *FITKAbaInteractionPropertyContact::getBehavoir(FITKAbaInteractionContactBehaviorEnum::FITKAbaContactBehaviorType type)
{
    for (auto b : m_behaviors)
    {
        if (b->getBehaviorType() == type)
            return b;
    }
    return nullptr;
}

void FITKAbaInteractionPropertyContact::clearAllBehaviors()
{
    for (FITKAbaInteractionContactBehavior* b: m_behaviors)
    {
        delete b;
    }
    m_behaviors.clear();
}

}
